package top.tangyh.lamp.care.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.tangyh.lamp.care.common.ObsrvCfgValUnil;
import top.tangyh.lamp.care.entity.BObsvCfg;
import top.tangyh.lamp.care.mapper.BObsvCfgMapper;
import top.tangyh.lamp.care.mapper.BObsvPtCfgMapper;
import top.tangyh.lamp.care.service.BObsvCfgService;
import top.tangyh.lamp.care.service.BObsvPtCfgService;
import top.tangyh.basic.base.service.impl.SuperServiceImpl;
import top.tangyh.lamp.care.manager.BObsvPtCfgManager;
import top.tangyh.lamp.care.entity.BObsvPtCfg;
import top.tangyh.lamp.care.vo.query.ObsvCfgQueryParam;
import top.tangyh.lamp.care.vo.query.ObsvPtCfgForRdParam;
import top.tangyh.lamp.care.vo.query.ObsvPtCfgQueryParam;
import top.tangyh.lamp.care.vo.result.*;
import top.tangyh.lamp.care.vo.save.BObsvPtCfgSaveVO;
import top.tangyh.lamp.care.vo.save.ObsvPtCfgParam;
import top.tangyh.lamp.care.vo.update.BObsvPtCfgUpdateVO;
import top.tangyh.lamp.care.vo.query.BObsvPtCfgPageQuery;
import top.tangyh.lamp.common.constant.CommonConstant;
import top.tangyh.lamp.common.constant.ObsvConstant;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 病人观察项目配置表
 * </p>
 *
 * @author zqb
 * @date 2024-07-26 10:31:53
 * @create [2024-07-26 10:31:53] [zqb] [代码生成器生成]
 */
@Slf4j
@RequiredArgsConstructor
@Service
@Transactional(readOnly = true)
public class BObsvPtCfgServiceImpl extends SuperServiceImpl<BObsvPtCfgManager, Long, BObsvPtCfg> implements BObsvPtCfgService {

    private final BObsvCfgService bObsvCfgService;


    private final BObsvPtCfgMapper bObsvPtCfgMapper;

    /**
     * 属性值单位字段名
     */
    private final static String PROP_UNIT = "propUnit";
    /**
     * 下限字段名
     */
    private final static String REF_LOWER = "refLower";
    /**
     * 上限字段名
     */
    private final static String REF_UPPER = "refUpper";

    private final BObsvCfgMapper bObsvCfgMapper;

    /**
     * 查询用于观察记录的配置项编码集合，按观察项类别返回
     */
    @Override
    public Map<String, Set<String>> getObsvCodeSetFinalOfLeafByType(ObsvPtCfgForRdParam param, Set<String> obsrvypeFillte) {
        Map<String, Set<String>> rst = new LinkedHashMap<>();
        //获得最终可用配置项目集合
        List<ObsvCfgForRdDto> cfgList = queryForRd(param);

        for (ObsvCfgForRdDto cfgType : cfgList) {
            if (cfgType == null || CollectionUtil.isEmpty(cfgType.getDetail())) {
                continue;
            }
            if (CollectionUtil.isNotEmpty(obsrvypeFillte) && !obsrvypeFillte.contains(cfgType.getObsvType())) {
                continue;
            }

            Set<String> set = rst.get(cfgType.getObsvType());
            if (set == null) {
                set = new LinkedHashSet<>();
                rst.put(cfgType.getObsvType(), set);
            }
            //由观察项主从记录中生成 观察标识集合 （结构体的观察标识会被过滤）
            copyObsrvcOodeSet(set, cfgType.getDetail());
        }
        return rst;
    }

    /**
     * 由观察项主从记录中生成 观察标识集合 （结构体的观察标识会被过滤）
     */
    private void copyObsrvcOodeSet(Set<String> set, List<ObsvCfgDto> list) {
        if (CollectionUtil.isEmpty(list)) {
            ;
        }
        if (set == null) {
            set = new LinkedHashSet<>();
        }
        for (ObsvCfgDto cfgHead : list) {
            if (cfgHead == null) {
                continue;
            }
            if (!ObsvConstant.TYPE_STRUCT.equals(cfgHead.getDataType())
                    && CommonConstant.YES_NUMBER == cfgHead.getIsEnable().intValue()
                    && CommonConstant.YES_NUMBER == cfgHead.getIsVisible().intValue()
                    && CommonConstant.NO_NUMBER == cfgHead.getIsDeleted().intValue()
            ) {
                set.add(cfgHead.getObsvCode());
            } else if (CollectionUtil.isNotEmpty(cfgHead.getDetail())) {
                for (ObsvCfgDetailDto cfgDetail : cfgHead.getDetail()) {
                    if (!ObsvConstant.TYPE_STRUCT.equals(cfgHead.getDataType())
                            && CommonConstant.YES_NUMBER == cfgHead.getIsEnable().intValue()
                            && CommonConstant.YES_NUMBER == cfgHead.getIsVisible().intValue()
                            && CommonConstant.NO_NUMBER == cfgHead.getIsDeleted().intValue()
                    ) {
                        set.add(cfgHead.getObsvCode());
                    }
                }
            }
        }


    }


    /**
     * 查询观察项个性配置，该配置适用于观察记录查询所需全局配置，返回是分类处理的 观察项配置集合
     *
     * @param param 观察项个性配置查询参数
     * @return
     */
    @Override
    public List<ObsvCfgForRdDto> queryForRd(ObsvPtCfgForRdParam param) {
        ObsvCfgQueryParam cfgParam = new ObsvCfgQueryParam();
        //查询观察项全局配置，返回值会分类
        List<ObsvCfgForRdDto> rst = bObsvCfgService.queryForRd(cfgParam);
        log.debug("观察项---------------全局配置:{}", JSON.toJSONString(rst));
        for (ObsvCfgForRdDto typeList : rst) {
            //过滤不可见 与 禁止启用的
            typeList.setDetail(typeList.getDetail().stream()
                    .filter(o -> o.getIsVisible() == CommonConstant.YES_NUMBER
                            && o.getIsEnable() == CommonConstant.YES_NUMBER)
                    .collect(Collectors.toList()));
        }
        log.debug("观察项---------------全局配置过滤后的值:{}", JSON.toJSONString(rst));

        //查询个性化配置参数
        ObsvPtCfgQueryParam ptParam = new ObsvPtCfgQueryParam();
        ptParam.setPatientIdent(param.getPatientIdent());
        ptParam.setIsDeleted(CommonConstant.NO_NUMBER);
        List<ObsvPtCfgDto> ptCfgList = bObsvPtCfgMapper.getObsvPtCfg(ptParam);
        Map<String, Map<String, ObsvPtCfgDto>> cach = new LinkedHashMap<>();
        if (CollectionUtil.isNotEmpty(ptCfgList)) {
            for (ObsvPtCfgDto item : ptCfgList) {
                Map<String, ObsvPtCfgDto> map = cach.get(item.getObsvType());
                if (map == null) {
                    map = new LinkedHashMap<>();
                    cach.put(item.getObsvType(), map);
                }
                map.put(item.getObsvCode(), item);
            }
        }
        if (CollectionUtil.isEmpty(cach)) {
            return rst;
        }
        log.debug("观察项---------------个性配置:{}", JSON.toJSONString(cach));
        for (ObsvCfgForRdDto typeList : rst) {

            Map<String, ObsvPtCfgDto> cachCfg = cach.get(typeList.getObsvType());
            if (CollectionUtil.isEmpty(cachCfg)) {
                log.debug("观察项---------------综合处理，没有指定类别的观察项 {}", typeList.getObsvType());
                continue;
            }

            Iterator<ObsvCfgDto> it = typeList.getDetail().iterator();
            while (it.hasNext()) {
                ObsvCfgDto cfg = it.next();
                ObsvPtCfgDto ptCfgCache = cachCfg.get(cfg.getObsvCode());
                setRefVal(cfg, ptCfgCache);
                List<ObsvCfgDetailDto> detailCfgList = cfg.getDetail();
                if (CollectionUtil.isNotEmpty(detailCfgList)) {
                    for (ObsvCfgDetailDto detailCfg : detailCfgList) {
                        ObsvPtCfgDto ptCfgDetailCache = cachCfg.get(detailCfg.getObsvCode());
                        setRefVal(detailCfg, ptCfgDetailCache);
                    }
                }


                if (!cachCfg.containsKey(cfg.getObsvCode())) {
                    it.remove();
                }
                if (cachCfg.get(cfg.getObsvCode()) != null && cachCfg.get(cfg.getObsvCode()).getIsVisible().intValue() == CommonConstant.NO_NUMBER) {
                    it.remove();
                }

            }
        }
        log.debug("观察项---------------最后处理结果:{}", JSON.toJSONString(rst));
        return rst;
    }

    private void setRefVal(Object cfg, ObsvPtCfgDto ptCfgCache) {
        if (!((cfg instanceof ObsvCfgDto) || (cfg instanceof ObsvCfgDetailDto))) {
            return;
        }
        if (ptCfgCache != null && StrUtil.isNotBlank(ptCfgCache.getPropUnit())) {
            BeanUtil.setProperty(cfg, PROP_UNIT, ptCfgCache.getPropUnit());
        }
        if (ptCfgCache != null && ptCfgCache.getRefLower() != null) {
            BeanUtil.setProperty(cfg, REF_LOWER, ptCfgCache.getRefLower());
        }
        if (ptCfgCache != null && ptCfgCache.getRefUpper() != null) {
            BeanUtil.setProperty(cfg, REF_UPPER, ptCfgCache.getRefUpper());
        }

    }


    /**
     * 查询用于观察记录的配置项编码集合
     */
    @Override
    public Set<String> getObsvCodeSetFinalOfLeaf(ObsvPtCfgForRdParam param) {
        //获得最终可用配置项目集合
        List<ObsvCfgForRdDto> cfgList = queryForRd(param);
        Set<String> set = new LinkedHashSet<>();
        for (ObsvCfgForRdDto cfgType : cfgList) {
            if (cfgType == null || CollectionUtil.isEmpty(cfgType.getDetail())) {
                continue;
            }
            //由观察项主从记录中生成 观察标识集合 （结构体的观察标识会被过滤）
            copyObsrvcOodeSet(set, cfgType.getDetail());
        }
        return set;
    }

    @Override
    public List<ObsvPtCfgDto> getObsvPtCfg(ObsvPtCfgQueryParam param) {

        List<ObsvPtCfgDto> rst = allowSelect(param);
        param.setIsDeleted(CommonConstant.NO_NUMBER);
        List<ObsvPtCfgDto> ptCfgList = bObsvPtCfgMapper.getObsvPtCfg(param);
        Map<String, ObsvPtCfgDto> cache = new LinkedHashMap<>();
        if (CollectionUtil.isNotEmpty(ptCfgList)) {
            cache = ptCfgList.stream().filter(item -> item != null && StrUtil.isNotBlank(item.getObsvCode()))
                    .collect(Collectors.toMap(ObsvPtCfgDto::getObsvCode, item -> item, (k1, k2) -> k2));
        }

        for (ObsvPtCfgDto cfg : rst) {
            ObsvPtCfgDto ptCfg = cache.get(cfg.getObsvCode());
            if (CollectionUtil.isNotEmpty(cache) && ptCfg == null) {
                cfg.setIsVisible(CommonConstant.NO_NUMBER);
            } else if (ptCfg != null) {
                cfg.setIsVisible(ptCfg.getIsVisible());
                if (StrUtil.isNotBlank(ptCfg.getPropUnit())) {
                    cfg.setPropUnit(ptCfg.getPropUnit());
                }
                if (StrUtil.isNotBlank(ptCfg.getRefLower())) {
                    cfg.setRefLower(ptCfg.getRefLower());
                }
                if (StrUtil.isNotBlank(ptCfg.getRefUpper())) {
                    cfg.setRefUpper(ptCfg.getRefUpper());
                }
                if (StrUtil.isNotBlank(ptCfg.getPatientIdent())) {
                    cfg.setPatientIdent(ptCfg.getPatientIdent());
                }
                if (StrUtil.isNotBlank(ptCfg.getHospitalNumber())) {
                    cfg.setHospitalNumber(ptCfg.getHospitalNumber());
                }
                //小数位数
                ObsrvCfgValUnil.doCfgVal(cfg);
            } else {
                cfg.setIsVisible(CommonConstant.YES_NUMBER);
            }
        }

        return rst;
    }

    @Override
    public List<ObsvPtCfgDto> allowSelect(ObsvPtCfgQueryParam param) {
        LambdaQueryWrapper<BObsvCfg> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BObsvCfg::getIsEnable, CommonConstant.YES_NUMBER);
        queryWrapper.eq(BObsvCfg::getIsDeleted, CommonConstant.NO_NUMBER);
        queryWrapper.eq(BObsvCfg::getIsVisible, CommonConstant.YES_NUMBER);
        queryWrapper.eq(StrUtil.isNotBlank(param.getObsvType()), BObsvCfg::getObsvType, param.getObsvType());
        queryWrapper.orderByDesc(BObsvCfg::getOrderNo);

        List<BObsvCfg> list = bObsvCfgMapper.selectList(queryWrapper);
        List<ObsvPtCfgDto> rst = new ArrayList<>();
        for (BObsvCfg cfg : list) {
            ObsvPtCfgDto dto = BeanUtil.copyProperties(cfg, ObsvPtCfgDto.class);
            dto.setObsvId(cfg.getId());
            rst.add(dto);
        }
        return rst;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertAndUpdate(ObsvPtCfgParam param) {
        List<ObsvPtCfgParamHandle> paramHandler = param.getList();
        if (CollectionUtil.isEmpty(paramHandler)) {
            return 0;
        }
        int i = 0;
        Date currDate = new Date();
        for (ObsvPtCfgParamHandle item : paramHandler) {
            LambdaQueryWrapper<BObsvPtCfg> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BObsvPtCfg::getPatientIdent, item.getPatientIdent());
            queryWrapper.eq(BObsvPtCfg::getObsvCode, item.getObsvCode());

            BObsvPtCfg yxObsvPtCfg = BeanUtil.copyProperties(item, BObsvPtCfg.class);
            List<BObsvPtCfg> list = bObsvPtCfgMapper.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(list)) {
                LambdaUpdateWrapper<BObsvPtCfg> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(BObsvPtCfg::getRefLower, yxObsvPtCfg.getRefLower());
                updateWrapper.set(BObsvPtCfg::getRefUpper, yxObsvPtCfg.getRefUpper());
                updateWrapper.eq(BObsvPtCfg::getPatientIdent, item.getPatientIdent());
                updateWrapper.eq(BObsvPtCfg::getObsvCode, item.getObsvCode());
                bObsvPtCfgMapper.update(yxObsvPtCfg, updateWrapper);
            } else {
                yxObsvPtCfg.setId(null);
                bObsvPtCfgMapper.insert(yxObsvPtCfg);
            }
            i++;
        }
        return i;
    }
    
    
}


